home *** CD-ROM | disk | FTP | other *** search
- ⓪ ⓪ IMPLEMENTATION MODULE ALAP;⓪ (*$H+,Z+,S-,R-*)⓪ ⓪ FROM SYSTEM IMPORT ADR, ASSEMBLER, BITNUM, BYTE, WORD, LONGWORD, ADDRESS, SHIFT;⓪ FROM GEMDOS IMPORT Super;⓪ FROM Storage IMPORT ALLOCATE;⓪ ⓪ (* I/O-Routinen für Testausgaben *)⓪ IMPORT InOut;⓪ ⓪ CONST NMI_Mask = $0700;⓪ ⓪((* alle Zeitwerte sind in µs angegeben *)⓪(bitTime = 5 (* 4.34 *);⓪(byteTime = 39;⓪(IDGslottime = 200;⓪(maxIFGtime = 400; (* 200 ist für ENQ->ACK offenbar zu klein. *)⓪(minIDGtime = 2*maxIFGtime;⓪ ⓪ CONST CTLA = $FFFF8C81;⓪ ⓪ (* -------------------------------------------------- *)⓪ ⓪ PROCEDURE resetRx;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(; resetRx⓪(MOVE.B #3,(A1)⓪(MOVE.B #$D0,(A1) ; disableRx⓪(MOVEQ #2,D0⓪&flushFIFO:⓪(TST.B 2(A1)⓪(DBRA D0,flushFIFO⓪(MOVE.B #$30,(A1) ; reset error⓪(MOVE.B #$20,(A1) ; enable IR on next Rx⓪(MOVE.B #3,(A1)⓪(MOVE.B #rxEnable,(A1) ; enableRx⓪$END⓪"END resetRx;⓪"(*$L=*)⓪"⓪ ⓪ CONST rnda = 1664525; (* Knuth S.102 Zeile 26 *)⓪'rndc = 117; (* teilerfremd mit 2^32 für max. Periode 2^32 *)⓪ ⓪ PROCEDURE random;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; IN: D0.W max-Wert minus 1, OUT: D0.W 0..max-1⓪(MOVE.W D0,-(A7)⓪(MOVE.L seed,D0⓪(BNE isInit⓪(; seek initialisieren⓪(MOVEM.L A0-A2,-(A7)⓪(MOVE #17,-(A7)⓪(TRAP #14⓪(ADD.L D0,seed⓪(TRAP #14⓪(ADDQ.L #2,A7⓪(MOVEM.L (A7)+,A0-A2⓪(LSL.L #8,D0⓪(ADD.L D0,seed⓪&isInit:⓪(MOVE.L D0,D1⓪(MOVE.L D0,D2⓪(SWAP D2⓪(MOVE.L D3,-(A7)⓪(MOVE.L #rnda,D3⓪(MULU D3,D0⓪(MULU D3,D2⓪(SWAP D3⓪(MULU D3,D1⓪(MOVE.L (A7)+,D3⓪(SWAP D1⓪(CLR.W D1⓪(SWAP D2⓪(CLR.W D2⓪(ADD.L D1,D0⓪(ADD.L D2,D0⓪(ADDI.L #rndc,D0⓪(MOVE.L D0,seed⓪(MOVE.W (A7)+,D1⓪(BEQ rtn0⓪(MOVE.W D0,D2⓪(CLR.W D0⓪(SWAP D0⓪(DIVU D1,D0⓪(MOVE.W D2,D0⓪(DIVU D1,D0⓪(SWAP D0⓪(RTS⓪&rtn0⓪(MOVEQ #0,D0⓪$END⓪"END random;⓪"(*$L=*)⓪ ⓪ PROCEDURE WriteFrame (REF packet: aPacket; no: CARDINAL);⓪"VAR n: CARDINAL;⓪"BEGIN⓪$FOR n:= 1 TO 5 DO⓪&IF n > packet.length THEN⓪(InOut.WriteString (' ');⓪&ELSE⓪(InOut.WriteHex (LONG (packet.frame.rawData [n]), 3);⓪&END⓪$END;⓪$FOR n:= 6 TO no DO⓪&IF n <= packet.length THEN⓪(InOut.WriteHex (LONG (packet.frame.rawData [n]), 3);⓪(IF (ORD (packet.frame.rawData [n]) >= 32) AND⓪+(ORD (packet.frame.rawData [n]) < 128) THEN⓪*InOut.Write ('/');⓪*InOut.Write (CHAR(packet.frame.rawData [n]));⓪(END⓪&END⓪$END;⓪$InOut.WriteString (' ');⓪"END WriteFrame;⓪ ⓪ PROCEDURE WriteStatus (status: FrameStatus);⓪"BEGIN⓪$CASE status OF⓪&|badframeCRC: InOut.WriteString ('>badframeCRC<')⓪&|badframeSize: InOut.WriteString ('>badframeSize<');⓪&|badframeType: InOut.WriteString ('>badframeType<')⓪&|overrunError: InOut.WriteString ('>overrunError<')⓪&|underrunError: InOut.WriteString ('>underrunError<')⓪&|lostAddress: InOut.WriteString ('>lost address<')⓪&|lapACKframe: InOut.WriteString ('>ACKframe<')⓪&|lapENQframe: InOut.WriteString ('>ENQframe<');⓪&|lapRTSframe: InOut.WriteString ('>RTSframe<');⓪&|lapCTSframe: InOut.WriteString ('>CTSframe<');⓪&|lapDATAframe: InOut.WriteString ('>DATAframe<');⓪&|noFrame: InOut.WriteString ('no frame!');⓪$ELSE⓪&InOut.WriteString ('unknown frame!');⓪$END;⓪"END WriteStatus;⓪ ⓪ (* --------------------------- *)⓪ ⓪ FORWARD AcquireAddress;⓪ FORWARD TransmitPacket;⓪ FORWARD TransmitFrame;⓪ FORWARD ReceiveFrame (VAR packet: ptrPacket): FrameStatus;⓪ FORWARD ReceiveLinkMgmt (VAR packet: ptrPacket): ReceiveStatus;⓪ FORWARD IR_Handler;⓪ FORWARD GetFrame;⓪ ⓪ PROCEDURE NewPacketBuffer;⓪"VAR p, prev, last: ptrPacket; sr: CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE SR,sr(A6)⓪(MOVE #$2500,SR⓪$END;⓪$NEW (p);⓪$IF p # NIL THEN⓪&IF packetBuffers = 0 THEN⓪(headPacket:= p;⓪(tailPacket:= p;⓪(last:= p⓪&ELSE⓪(prev:= headPacket;⓪(WHILE prev^.next # tailPacket DO⓪*prev:= prev^.next⓪(END;⓪(last:= prev^.next;⓪(prev^.next:= p⓪&END;⓪&INC (packetBuffers);⓪&WITH p^ DO⓪(next:= last;⓪(status:= undefined;⓪(no:= packetBuffers⓪&END;⓪$END;⓪$ASSEMBLER⓪(MOVE sr(A6),SR⓪$END;⓪"END NewPacketBuffer;⓪ ⓪ PROCEDURE ResetReceiveBuffer;⓪"BEGIN⓪$tailPacket:= headPacket⓪"END ResetReceiveBuffer;⓪ ⓪ TABLE.W SCCInitData:⓪*$09C0, $0420, $0AE0, $0600, $077E, $0C06, $0D00, $0EC0,⓪*$03D0, $0B70, $0E21, $0560, $0F00, $0108,⓪*$0200 + ADR (IR_Vector) DIV 4, $0908, $0300+rxEnable, 0;⓪ ⓪ (*$L-*)⓪ ⓪ PROCEDURE Init;⓪"(* IN: D0.B: proposed address, 0 if none *)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.B D0,myAddress⓪(CLR backoff⓪(CLR.B deferHistory⓪(CLR.B collsnHistory⓪(⓪(JSR NewPacketBuffer⓪(JSR NewPacketBuffer⓪(JSR NewPacketBuffer⓪$⓪(; Init Timer A⓪(MOVEA.W #$FA00,A0⓪(MOVE.B #$00,$19(A0) ; TACR: Timer Stop⓪(ANDI.B #$DF,$13(A0) ; IMRA: Mask Timer A IR⓪(ORI.B #$20,$07(A0) ; IERA: Enable Timer-A Pending Bit⓪(MOVE.B #$DF,$0B(A0) ; IPRA: Clear Timer-A Pending Bit⓪ ⓪%; *** SCC initialisieren ***⓪%;⓪%; Die Clock an RTxCA ist 3.672 MHz, benötigte Baudrate ist 230400 Bit/s.⓪%; Dazu müßte die Clock auf 1/16 geteilt werden.⓪%; Da für Receive DPLL verwendet wird, und DPLL den 16fachen Clk⓪%; braucht, wird trotzdem kein Teiler verwendet. Stattdessen wird⓪%; über den BRG geteilt.⓪%;⓪%; Der SCC arbeitet im Interrupt-Betrieb. Es wird der Non-Auto-Vektor-⓪%; Modus verwendet, auf Adr. $360. Der IR läuft im Level 5.⓪%; Da nur eine einzige IR-Quelle benutzt wird (IR on 1st Rx Char or⓪%; special condition), wird die vector-includes-status-Option nicht⓪%; verwerdet.⓪%;⓪ ⓪(; GIOffBit ($7F);⓪(MOVE.W #$7F,-(A7)⓪(MOVE #29,-(A7)⓪(TRAP #14⓪(ADDQ.L #4,A7⓪(⓪(MOVE.L #IR_Handler,IR_Vector⓪(⓪(LEA SCCInitData,A0⓪(MOVEA.W #CTLA,A1⓪$l1: MOVE.W (A0)+,D0⓪(BEQ e1⓪(MOVE.W D0,D1⓪(LSR #8,D1⓪(MOVE.B D1,(A1)⓪(NOP⓪(MOVE.B D0,(A1)⓪(BRA l1⓪$e1:⓪(MOVE.B myAddress,D0⓪(JSR AcquireAddress⓪(⓪(CLR deferCount⓪(CLR collsnCount⓪(CLR DataFramesOut⓪(CLR RTSFramesOut⓪(CLR CTSFramesOut⓪$END⓪"END Init;⓪ ⓪ VAR acqFrame: aTxFrame;⓪ ⓪ PROCEDURE AcquireAddress;⓪"(* IN: D0.B: proposed address, 0 if none *)⓪"BEGIN⓪$ASSEMBLER⓪(; *** choose address ***⓪(BSR getNewAddress⓪(CLR fAdrValid⓪(SUBQ #2,A7⓪&acqlp2:⓪(CLR fAdrInUse⓪(MOVE.W #wksTries,(A7)⓪&acqlp:⓪(; TransmitPacket (myAddress, lapENQ, ENQframe.dataField, 0)⓪(LEA acqFrame,A0⓪(MOVE.B myAddress,D0⓪(MOVE.B D0,aTxFrame.ctrl.dstAddr(A0)⓪(MOVE.B D0,aTxFrame.ctrl.srcAddr(A0)⓪(MOVE.B #lapENQ,aTxFrame.ctrl.lapType(A0)⓪(CLR.W aTxFrame.dataCnt1(A0)⓪(CLR.W aTxFrame.dataCnt2(A0)⓪(JSR TransmitPacket⓪(CMPI #transmitOK,D0⓪(BEQ adrIsUsed⓪(TST fAdrInUse⓪(BEQ adrNotUsed⓪ adrIsUsed:⓪(MOVEQ #0,D0⓪(BSR getNewAddress⓪(BRA acqlp2⓪ adrNotUsed:⓪(SUBQ #1,(A7)⓪(BNE acqlp⓪(ADDQ #2,A7⓪(MOVE #1,fAdrValid⓪(RTS⓪ ⓪ getNewAddress:⓪(TST.B D0⓪(BNE takeIt⓪(MOVEQ #127,D0⓪(JSR random⓪(ADDQ #1,D0⓪&takeIt:⓪(MOVE.B D0,myAddress⓪(; setAddress⓪(MOVEA.W #CTLA,A1⓪(MOVE.B #6,(A1)⓪(MOVE.B myAddress,(A1)⓪$END;⓪"END AcquireAddress;⓪ ⓪ PROCEDURE TransmitPacket;⓪"(* IN: A0: ^aTxFrame⓪%OUT: D0.W TransmitStatus *)⓪ ⓪"PROCEDURE BitCount;⓪$BEGIN⓪&ASSEMBLER⓪*; In: D0.B, Out: D1.W /D0-D2/⓪*MOVEQ #0,D1⓪*MOVEQ #7,D2⓪'l: LSR.B #1,D0⓪*BCC c⓪*ADDQ #1,D1⓪'c: DBRA D2,l⓪&END⓪$END BitCount;⓪"⓪"BEGIN (* TransmitPacket *)⓪$ASSEMBLER⓪(TST fAdrInUse⓪(BEQ notInUse⓪(MOVEQ #dupAddress,D0⓪(RTS⓪¬InUse:⓪(MOVE.L A0,-(A7)⓪(⓪(LEA RTSframe,A1⓪(MOVE.B aTxFrame.ctrl.dstAddr(A0),aTxFrame.ctrl.dstAddr(A1)⓪(MOVE.B myAddress,aTxFrame.ctrl.srcAddr(A1)⓪(MOVE.B #lapRTS,aTxFrame.ctrl.lapType(A1)⓪(CLR.W aTxFrame.dataCnt1(A1)⓪(CLR.W aTxFrame.dataCnt2(A1)⓪(⓪(MOVE.B collsnHistory,D0⓪(BSR BitCount⓪(CMPI #2,D1⓪(BLS c1⓪(⓪(; increase backoff because of too many collisions⓪(CLR.B collsnHistory⓪(MOVE.W backoff,D0⓪(BEQ c2⓪(LSL #1,D0⓪(CMPI #16,D0⓪(BLS c3⓪(MOVEQ #16,D0⓪(BRA c3⓪$c2: MOVEQ #2,D0⓪$c3: MOVE D0,backoff⓪(⓪$c1: MOVE.B deferHistory,D0⓪(BSR BitCount⓪(CMPI #2,D1⓪(BCC c4⓪(⓪(; decrease backoff if no defers recently⓪(CLR.B deferHistory⓪(LSR.W backoff⓪(⓪$c4: ; shift history data⓪(LSL collsnHistory⓪(LSL deferHistory⓪(⓪(CLR.W deferTries⓪(CLR.W collsnTries⓪(MOVE.W backoff,lclbackoff⓪(⓪(MOVEA.W #CTLA,A1⓪(MOVEA.W #$FA00,A2⓪(⓪ again1: ; *** main loop ***⓪(⓪(; *** defer while there are other transmissions in progress ***⓪(⓪(; carrierSense?⓪(BTST #4,CTLA⓪(BNE.W noCarrier⓪(⓪(BRA defer1⓪(⓪&defer2:⓪(ADDQ.W #1,deferCount⓪(ADDQ.W #1,deferTries⓪(CMPI.W #maxDefers,deferTries⓪(BLS defer1⓪(⓪(; *** Error: too many defers ***⓪(MOVE.W #excessDefers,D0⓪(BRA.W exit⓪(⓪&defer1:⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; defer⓪(CMPI #2,lclbackoff⓪(BCC c5⓪(MOVE #2,lclbackoff⓪&c5:⓪(BSET #0,deferHistory⓪(⓪(; wait for packet to pass⓪(; Delay: maxFrameSize * 1.5 * byteTime (39µs) = maxFrameSize * 58.5 Zyklen⓪(MOVE #maxFrameSize,D1⓪(MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #36,$1F(A2) ; TADR: Set Timer Count⓪(MOVE.B #1,$19(A2) ; TACR: Timer Start (Teiler: 1/4)⓪(BRA c6⓪$l6: BTST #4,CTLA⓪(BNE c7 ; kein Carrier mehr⓪(BTST #5,$0B(A2)⓪(BEQ c6⓪(MOVE.B #$DF,$0B(A2) ; time over: Clear Timer-A Pending Bit⓪$c6: DBRA D1,l6⓪(⓪(; something is wrong: ResetRx⓪(JSR resetRx⓪$c7: MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪&noCarrier:⓪(⓪(; resetMissingClock⓪(MOVE.B #14,(A1)⓪(MOVE.B #$41,(A1)⓪(⓪(; wait for min. IDG time after packet or idle line⓪(MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #minIDGtime DIV 4,$1F(A2) ; Set Timer Count⓪(MOVE.B #2,$19(A2) ; TACR: Timer Start (Teiler: 1/10)⓪$l7: BTST #4,CTLA⓪(BEQ defer1 ; erneut Carrier aufgetreten⓪(BTST #5,$0B(A2) ; IPRA⓪(BEQ l7⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; wait additional backoff time, deferring to others⓪(MOVE lclbackoff,D0⓪(BEQ n8⓪(ADDQ #1,D0⓪(JSR random⓪$n8: MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #IDGslottime DIV 4,$1F(A2) ; Set Timer Count⓪(MOVE.B #2,$19(A2) ; TACR: Timer Start (Teiler: 1/10)⓪(BRA c8⓪$l8: BTST #4,CTLA⓪(BEQ defer2 ; erneut Carrier aufgetreten⓪(BTST #5,$0B(A2) ; IPRA⓪(BEQ l8⓪(MOVE.B #$DF,$0B(A2) ; time over: Clear Timer-A Pending Bit⓪$c8: DBRA D0,l8⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; missing clock?⓪(MOVE.B #10,(A1)⓪(TST.B (A1) ; RR10⓪(BMI defer2⓪(⓪(; *** send RTS ***⓪(⓪(MOVE.L (A7),A0⓪(CMPI.B #lapENQ,aTxFrame.ctrl.lapType(A0)⓪(BEQ sndENQ⓪(LEA RTSframe,A0⓪ sndENQ: MOVE SR,D2⓪(ORI #NMI_Mask,SR⓪(ADDQ.W #1,RTSFramesOut⓪(JSR TransmitFrame⓪(⓪(; enableRx⓪(MOVE.B #3,(A1)⓪(MOVE.B #rxEnable,(A1)⓪(⓪(MOVE #1,fCTSexpected⓪(MOVE D2,SR⓪(; *** wait for CTS ***⓪(SUBQ.L #4,A7⓪(MOVE.L A7,(A3)+⓪(MOVEM.L A1/A2,-(A7)⓪(JSR ReceiveFrame/⓪(MOVEM.L (A7)+,A1/A2⓪(ADDQ.L #4,A7⓪(CLR fCTSexpected⓪(⓪(TST fAdrInUse⓪(BEQ noDup⓪(⓪(; *** Error: duplicate address ***⓪(MOVE.W #dupAddress,D0⓪(BRA.W exit⓪(⓪ noDup: MOVE.L (A7),A0⓪(CMPI.B #$FF,aTxFrame.ctrl.dstAddr(A0)⓪(BNE chkCTS⓪(; broadcast-Transmit auswerten⓪(CMPI #noFrame,D0⓪(BNE error1⓪(BRA send2⓪ chkCTS: CMPI #lapCTSframe,D0⓪(BNE error1⓪(CMPI.B #lapENQ,aTxFrame.ctrl.lapType(A0)⓪(BEQ error1⓪(⓪ send2: ; *** eigentliches Paket senden ***⓪(MOVE SR,D2⓪(BREAK ;ORI #NMI_Mask,SR⓪(ADDQ.W #1,DataFramesOut⓪(JSR TransmitFrame⓪(⓪(; enableRx⓪(MOVE.B #3,(A1)⓪(MOVE.B #rxEnable,(A1)⓪(⓪(MOVE D2,SR⓪(MOVE.W #transmitOK,D0⓪(BRA.W exit⓪(⓪ error1 ; assume collision because we didn't receive the expected CTS⓪(ADDQ #1,collsnCount⓪(BSET #0,collsnHistory⓪(ADDQ #1,collsnTries⓪(CMPI #maxCollsns,collsnTries⓪(BHI excssC⓪(⓪(MOVE.W lclbackoff,D0⓪(BEQ c12⓪(LSL #1,D0⓪(CMPI #16,D0⓪(BLS c13⓪(MOVEQ #16,D0⓪(BRA c13⓪#c12: MOVEQ #2,D0⓪#c13: MOVE D0,lclbackoff⓪(⓪(BRA again1⓪(⓪ excssC: ; *** Error: too many collisions ***⓪(MOVE.W #excessCollsns,D0⓪ exit: ADDQ.L #4,A7⓪$END;⓪"END TransmitPacket;⓪ ⓪ PROCEDURE TransmitFrame;⓪"BEGIN⓪$ASSEMBLER⓪(; A0: ^aTxFrame, A1: CTLA, A2: $FFFFFA00⓪(; enableTxDrivers⓪(MOVE.B #5,(A1)⓪(MOVE.B #setRTS,(A1)⓪(⓪(; Pause f. Sync-Pulse (1 Bit: 1.5 * bitTime (6.51µs) = 16 Zyklen)⓪(MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #4,$1F(A2) ; TADR: Set Timer Count⓪(MOVE.B #1,$19(A2) ; TACR: Timer Start (Teiler: 1/4)⓪%l: BTST #5,$0B(A2) ; IPRA⓪(BEQ l⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; disableTxDrivers⓪(MOVE.B #5,(A1)⓪(MOVE.B #$60,(A1)⓪(⓪(; Pause f. Sync-Pulse (1 Bit: 1.5 * bitTime (6.51µs) = 16 Zyklen)⓪(MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #4,$1F(A2) ; TADR: Set Timer Count⓪(MOVE.B #1,$19(A2) ; TACR: Timer Start (Teiler: 1/4)⓪%l2 BTST #5,$0B(A2) ; IPRA⓪(BEQ l2⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; enableTxDrivers, enableTx⓪(MOVE.B #5,(A1)⓪(MOVE.B #txEnable,(A1)⓪(⓪(; disableRx⓪(MOVE.B #3,(A1)⓪(MOVE.B #$D0,(A1)⓪(⓪(; 2 * txFlag⓪(; Delay: 2 * 1.5 * byteTime (39µs) = 116 Zyklen⓪(MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #70,$1F(A2) ; TADR: Set Timer Count⓪(MOVE.B #1,$19(A2) ; TACR: Timer Start (Teiler: 1/4)⓪%l3 BTST #5,$0B(A2) ; IPRA⓪(BEQ l3⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; resetCRC⓪(MOVE.B #$80,(A1)⓪(⓪(BSR TxChar⓪(BSR TxChar⓪(BSR TxChar⓪(ADDQ.L #1,A0⓪(MOVE.L (A0)+,A2⓪(MOVE.W (A0)+,D0⓪(DBRA D0,nextChar1⓪(BRA allSent1⓪(⓪%TxChar:⓪(BTST #2,(A1)⓪(BEQ TxChar⓪(MOVE.B (A0)+,2(A1)⓪(RTS⓪(⓪%nextChar1:⓪(BTST #2,(A1)⓪(BEQ nextChar1⓪(MOVE.B (A2)+,2(A1)⓪(DBRA D0,nextChar1⓪%allSent1:⓪(MOVE.L (A0)+,A2⓪(MOVE.W (A0)+,D0⓪(DBRA D0,nextChar2⓪(BRA allSent2⓪%nextChar2:⓪(BTST #2,(A1)⓪(BEQ nextChar2⓪(MOVE.B (A2)+,2(A1)⓪(DBRA D0,nextChar2⓪%allSent2:⓪(⓪(; resetUnderrun⓪(MOVE.B #$C0,(A1)⓪(⓪(; TxFCS: wait for underrun⓪%notUnder:⓪(BTST #6,(A1)⓪(BEQ notUnder⓪(⓪(; TxFlag (?)⓪%notEmpty2:⓪(BTST #2,(A1)⓪(BEQ notEmpty2⓪(⓪(; enableTxDrivers, disableTx⓪(MOVE.B #5,(A1)⓪(MOVE.B #setRTS,(A1)⓪(⓪(; txONEs (?)⓪(; Delay: 1.5 * byteTime (39µs) = 58 Zyklen⓪(MOVEA.W #$FA00,A2⓪(MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #35,$1F(A2) ; TADR: Set Timer Count⓪(MOVE.B #1,$19(A2) ; TACR: Timer Start (Teiler: 1/4)⓪%l4 BTST #5,$0B(A2) ; IPRA⓪(BEQ l4⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(⓪(; disableTxDrivers⓪(MOVE.B #5,(A1)⓪(MOVE.B #$60,(A1)⓪(⓪(; resetMissingClock⓪(MOVE.B #14,(A1)⓪(MOVE.B #$41,(A1)⓪$END;⓪"END TransmitFrame;⓪ ⓪ (*$L+*)⓪ ⓪ PROCEDURE ReceivePacket (VAR dstParam: anAddress;⓪9VAR srcParam: anAddress;⓪9VAR typeParam: aLAPtype;⓪9VAR dataParam: aDataField;⓪9VAR dataLength: INTEGER);⓪"VAR status: ReceiveStatus; packet: ptrPacket;⓪"BEGIN⓪$REPEAT UNTIL (ReceiveLinkMgmt (packet) = receiveOK) OR InOut.KeyPressed ();⓪$WITH packet^.frame DO⓪&dstParam:= dstAddr;⓪&srcParam:= srcAddr;⓪&typeParam:= lapType;⓪&dataParam:= dataField (*!!! hier werden 600 Byte kopiert -> Ptr verw.*)⓪$END;⓪"END ReceivePacket;⓪ ⓪ PROCEDURE ReceiveLinkMgmt (VAR packet: ptrPacket): ReceiveStatus;⓪"⓪"VAR status: ReceiveStatus;⓪&rcvdStatus: FrameStatus;⓪&sr: CARDINAL;⓪"⓪"BEGIN⓪$ASSEMBLER⓪(MOVE SR,sr(A6)⓪(MOVE #$2500,SR⓪$END;⓪$status:= receiving;⓪$REPEAT⓪&rcvdStatus:= ReceiveFrame (packet);⓪&IF rcvdStatus # noFrame THEN⓪(InOut.WriteCard (packet^.no, 1); InOut.Write (' ');⓪(WriteFrame (packet^,99);⓪(InOut.WriteLn;⓪(WriteStatus (rcvdStatus); InOut.WriteLn;⓪&END;⓪&CASE rcvdStatus OF⓪&|badframeCRC, badframeSize, badframeType, overrunError, underrunError,⓪'lostAddress:⓪(status:= frameError⓪&|lapACKframe:⓪&|lapENQframe:⓪((* wird nun schon beim Empfang erledigt *)⓪(HALT⓪((*⓪*IF fAdrValid THEN⓪,WITH ACKframe DO⓪.dstAddr:= packet^.frame.srcAddr;⓪.srcAddr:= myAddress;⓪.lapType:= lapACK⓪,END;⓪,TransmitFrame (ACKframe, 3);⓪*ELSE⓪,fAdrInUse:= TRUE⓪*END;⓪*status:= nullReceive⓪(*)⓪&|lapRTSframe:⓪((* wird nun schon beim Empfang erledigt *)⓪(HALT⓪((*⓪*IF fAdrValid THEN⓪,WITH CTSframe DO⓪.dstAddr:= headPacket^.frame.srcAddr;⓪.srcAddr:= myAddress;⓪.lapType:= lapCTS⓪,END;⓪,TransmitFrame (CTSframe, 3);⓪*ELSE⓪,fAdrInUse:= TRUE;⓪,status:= nullReceive⓪*END;⓪(*)⓪&|lapDATAframe:⓪(IF fAdrValid THEN⓪*status:= receiveOK⓪(ELSE⓪*ASSEMBLER⓪+;BREAK⓪*END;⓪*fAdrInUse:= TRUE;⓪*status:= nullReceive⓪(END;⓪&|noFrame:⓪(status:= nullReceive⓪&ELSE⓪&END⓪$UNTIL status # receiving;⓪$ASSEMBLER⓪(MOVE sr(A6),SR⓪$END;⓪$RETURN status⓪"END ReceiveLinkMgmt;⓪ ⓪ PROCEDURE ReceiveFrame (VAR packet: ptrPacket): FrameStatus;⓪"⓪"VAR status: FrameStatus;⓪ ⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(MOVEA.W #$FA00,A2⓪(MOVE.L tailPacket,A0⓪(⓪(; *** warten auf Frame-Empfang (IR o. Polling) ***⓪(⓪(MOVEQ #0,D1⓪(⓪$l1: MOVE.B #$DF,$0B(A2) ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B #maxIFGtime DIV 4,$1F(A2) ; TADR: Set Timer Count⓪(MOVE.B #2,$19(A2) ; TACR: Timer Start (Teiler: 1/10)⓪$l0: ; zuerst prüfen, ob evtl. noch ein Frame zu pollen ist,⓪(; auch wenn noch weitere Pakete schon im Puffer warten.⓪(MOVE.B #3,(A1)⓪(BTST.B #5,(A1) ; RR3: Rx IR pending?⓪(BNE pollFrame⓪(CMPA.L headPacket,A0⓪(BNE gotFrame⓪(BTST #5,$0B(A2) ; time over?⓪(BEQ l0⓪(; IR-Receive nochmal prüfen, falls IR zw. vorigem CMP und Time-Chk kam.⓪(CMPA.L headPacket,A0⓪(BNE gotFrame⓪(⓪((*⓪(TST test⓪(BEQ timeout⓪(⓪(ADDQ #1,D1⓪(BRA l1⓪(*)⓪(⓪$timeout:⓪(; time out⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(MOVE.L packet(A6),A0⓪(CLR.L (A0)⓪(MOVE #noFrame,status(A6)⓪(BRA.W exit2⓪(⓪$gotFrame:⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(BRA exit⓪(⓪$pollFrame:⓪(MOVE SR,D2⓪(ORI #NMI_Mask,SR⓪(MOVE.B #$00,$19(A2) ; TACR: Timer Stop⓪(JSR GetFrame⓪(MOVE.B #1,(A1)⓪(MOVE.B #$08,(A1)⓪(MOVE D2,SR⓪(⓪$exit:⓪(MOVE.L tailPacket,D0⓪(MOVE.L packet(A6),A0⓪(MOVE.L D0,(A0)⓪(MOVE.L D0,A0⓪(MOVE aPacket.status(A0),status(A6)⓪(MOVE.L aPacket.next(A0),tailPacket⓪(⓪$exit2:⓪$END;⓪$RETURN status⓪"END ReceiveFrame;⓪ ⓪ PROCEDURE IR_Handler;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(ORI #NMI_Mask,SR⓪(MOVEM.L A0-A2/D0-D1,-(A7)⓪(⓪(MOVEA.W #$FA00,A2⓪(MOVEA.W #CTLA,A1⓪(JSR GetFrame⓪(⓪(ADDQ.W #1,Interrupts⓪(⓪(MOVEM.L (A7)+,A0-A2/D0-D1⓪(RTE⓪$END;⓪"END IR_Handler;⓪"(*$L=*)⓪ ⓪ PROCEDURE GetFrame;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; overrun?⓪(MOVE.B #1,(A1) ; RR1⓪(BTST.B #5,(A1)⓪(BNE isOverrun⓪(⓪(MOVE.L headPacket,A0⓪(⓪(MOVE.B 2(A1),D0 ; 1. char sofort holen⓪(MOVE.B D0,aPacket.frame(A0)⓪(⓪(MOVE.B #2,4(A1)⓪(BTST.B #0,4(A1) ; RR2B⓪(BNE specCond⓪(⓪(MOVEQ #100,D1⓪&wait2:⓪(BTST #0,(A1)⓪(DBNE D1,wait2⓪(; overrun?⓪(MOVE.B #1,(A1) ; RR1⓪(BTST.B #5,(A1)⓪(BNE isOverrun⓪(⓪(MOVE.B 2(A1),aPacket.frame+1(A0)⓪(⓪(MOVEQ #2,D0⓪(BRA nextChar⓪(⓪$specCond:⓪(⓪$again:⓪(CLR D0⓪(⓪$loop2:⓪(; overrun?⓪(MOVE.B #1,(A1) ; RR1⓪(BTST.B #5,(A1)⓪(BEQ noOverrun⓪(⓪$isOverrun:⓪(MOVE D0,aPacket.length(A0)⓪(MOVE.W #overrunError,aPacket.status(A0)⓪(BRA.W exit2⓪(⓪$timeOut:⓪(MOVE D0,aPacket.length(A0)⓪(MOVE.W #noFrame,aPacket.status(A0)⓪(BRA.W exit2⓪(⓪$noOverrun:⓪(MOVEQ #100,D1 ;!!! Wert OK?⓪&wait4:⓪(BTST #0,(A1)⓪(DBNE D1,wait4⓪(BEQ timeOut⓪(⓪(; *** read data ***⓪(CMPI.W #maxFrameSize,D0 ; incomingLength⓪(BCS getChar⓪(⓪$sizeError:⓪(MOVE D0,aPacket.length(A0)⓪(MOVE.W #badframeSize,aPacket.status(A0)⓪(BRA.W exit2⓪(⓪$getChar:⓪(; headPacket^.frame.rawData [incomingLength]:= rxData ()⓪(MOVE.B 2(A1),aPacket.frame(A0,D0.W) ; RR8⓪(ADDQ.W #1,D0 ; incomingLength⓪(⓪$nextChar:⓪$noDataNow:⓪(; end of frame?⓪(MOVE.B #1,(A1) ; RR1⓪(TST.B (A1)⓪(BPL loop2⓪(⓪(SUBQ.W #2,D0 ; incomingLength⓪(MOVE D0,aPacket.length(A0)⓪(⓪(CMPI.W #minFrameSize,D0⓪(BCS sizeError⓪(⓪(; resetRx⓪(MOVE.B #3,(A1)⓪(MOVE.B #$D0,(A1) ; disableRx⓪(⓪(; CRC OK?⓪(MOVE.B #1,(A1) ; RR1⓪(BTST.B #6,(A1)⓪(BEQ crcOK⓪(⓪(MOVE.W #badframeCRC,aPacket.status(A0)⓪(BRA.W exit2⓪(⓪$crcOK:⓪(; Stimmt 1. Byte (unsere Adr. oder #$FF)?⓪(MOVE.B aPacket.frame(A0),D0⓪(CMPI.B #$FF,D0⓪(BEQ adrOK⓪(CMP.B myAddress,D0⓪(BEQ adrOK⓪(⓪(MOVE.W #lostAddress,aPacket.status(A0)⓪(BRA.W exit2⓪(⓪%adrOK:⓪(; *** frameDone ***⓪(⓪(TST.W fAdrValid⓪(BEQ notValid⓪(⓪(MOVE.B aPacket.frame.lapType(A0),D0⓪(BMI ctrlFrame⓪(⓪(MOVE.W #lapDATAframe,aPacket.status(A0)⓪(BRA.W exit2⓪(⓪&ctrlFrame:⓪(CMPI.B #lapENQ,D0⓪(BEQ isENQ⓪(CMPI.B #lapACK,D0⓪(BEQ isACK⓪(CMPI.B #lapRTS,D0⓪(BEQ isRTS⓪(CMPI.B #lapCTS,D0⓪(BEQ isCTS⓪&badFrame:⓪(MOVE.W #badframeType,aPacket.status(A0)⓪(BRA exit2⓪&isENQ:⓪(MOVE.W #lapENQframe,aPacket.status(A0)⓪(⓪(BRA exit2⓪&isACK:⓪(MOVE.W #lapACKframe,aPacket.status(A0)⓪(MOVE.W #1,fAdrInUse⓪(BRA exit2⓪&isRTS:⓪(MOVE.W #lapRTSframe,aPacket.status(A0)⓪(BRA exit2⓪&isCTS:⓪(MOVE.W #lapCTSframe,aPacket.status(A0)⓪(TST.W fCTSexpected⓪(BNE exit2⓪(; das muß wieder hier rein (s. NOTES):⓪(MOVE.W #1,fAdrInUse⓪(BRA badFrame⓪(BRA isNoFrame ;!!!testweise⓪(⓪¬Valid:⓪(CMPI.B #$FF,aPacket.frame.dstAddr(A0)⓪(BEQ exit2⓪(⓪(;BREAK⓪(MOVE #1,fAdrInUse⓪&isNoFrame⓪(MOVE.W #noFrame,aPacket.status(A0)⓪(⓪$exit2:⓪(⓪(MOVEQ #2,D0⓪&flushFIFO:⓪(TST.B 2(A1)⓪(DBRA D0,flushFIFO⓪(⓪(; resetMissingClock⓪(;MOVE.B #14,(A1)⓪(;MOVE.B #$41,(A1)⓪(⓪(; reset error⓪(MOVE.B #$30,(A1)⓪(⓪(; reset IUS⓪(MOVE.B #$38,(A1)⓪(⓪(; resetMissingClock⓪(MOVE.B #14,(A1)⓪(MOVE.B #$41,(A1)⓪(⓪(⓪(CMPI.W #lapENQframe,aPacket.status(A0)⓪(BNE noENQ⓪(⓪(; ACK senden⓪(⓪(CLR.W -(A7)⓪(MOVE.B #lapACK,-(A7)⓪(BRA sendCtrlFrame⓪(⓪&noENQ:⓪(⓪(CMPI.W #lapRTSframe,aPacket.status(A0)⓪(BNE noRTS⓪(⓪(; CTS senden, falls kein Broadcast⓪(⓪(CMPI.B #$FF,aPacket.frame.dstAddr(A0)⓪(BEQ noCTS⓪(CLR.W -(A7)⓪(SUBQ.L #4,A7⓪(CLR.W -(A7)⓪(SUBQ.L #4,A7⓪(MOVE.B #lapCTS,-(A7)⓪&sendCtrlFrame:⓪(MOVE.B aPacket.frame.srcAddr(A0),D0⓪(LSL #8,D0⓪(MOVE.B myAddress,D0⓪(MOVE.W D0,-(A7)⓪(MOVE.L A7,A0⓪(ADDQ.W #1,CTSFramesOut⓪(JSR TransmitFrame⓪(ADDA.W #16,A7⓪(MOVE.L headPacket,A0⓪&noCTS:⓪(MOVE.W #noFrame,aPacket.status(A0)⓪(⓪&noRTS:⓪(⓪(ADDQ.W #1,FramesReceived⓪(⓪(MOVE.L aPacket.next(A0),A0⓪(MOVE.L A0,headPacket⓪(⓪(MOVE.B #$20,(A1) ; enable IR on next Rx⓪(⓪(MOVE.B #3,(A1)⓪(MOVE.B #rxEnable,(A1) ; enableRx⓪(⓪(; more IRs?⓪(BTST #0,(A1)⓪(BNE again⓪$END⓪"END GetFrame;⓪"(*$L=*)⓪ ⓪ BEGIN⓪"packetBuffers:= 0;⓪ END ALAP.⓪ ə
- (* $FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$00003AF1$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$00004A3B$00004919$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$000030B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8$FFEFD9B8Ç$000058A6T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$FFF006F0$000058A6$00005978$00003746$000001EC$0000371D$000037D9$00003640$000030A5$00003B02$00002DC7$00005886$FFF006F0$000058A6$00005883$00005876îÇé*)
-